<template>
	<el-card class="box-card">
		<template #header>
			<div class="card-header">
				<span class="title" v-if="scene === 0">就诊人管理</span>
				<span class="title" v-else-if="scene === 1">添加就诊人</span>
				<span class="title" v-else-if="scene === 2">编辑就诊人</span>

				<el-button class="button" type="success" v-if="scene === 0" :icon="User" @click="addPatient">
					添加就诊人
				</el-button>
				<el-button v-else type="primary" plain :icon="ArrowLeft" @click="() => router.back()"> 返回 </el-button>
			</div>
		</template>
		<!-- 展示结构 -->
		<div class="visitor_box" v-if="scene === 0" v-loading="loading">
			<Visitor
				v-for="item in patientInfo"
				:key="item.id"
				class="visitor"
				:data="item"
				delete-but
				@edit="editPatient(item.id)"
				@delete="deletePatientByIdFn(item.id)"></Visitor>
		</div>
		<!-- 修改/添加结构 -->
		<div class="form" v-else-if="scene === 1 || scene === 2" v-loading="formLoading">
			<el-divider content-position="left">就诊人信息</el-divider>
			<el-form :model="formData" :rules="rules" label-width="120px" ref="ruleFormRef1">
				<el-form-item label="用户姓名" prop="name">
					<el-input placeholder="请输入用户姓名" v-model="formData.name" />
				</el-form-item>
				<el-form-item label="证件类型" prop="certificatesType">
					<el-select placeholder="请选择证件类型" v-model="formData.certificatesType">
						<el-option
							v-for="item in certationType"
							:key="item.id"
							:label="item.name"
							:value="item.value" />
					</el-select>
				</el-form-item>
				<el-form-item label="证件号码" prop="certificatesNo">
					<el-input placeholder="请输入证件号码" v-model="formData.certificatesNo" />
				</el-form-item>
				<el-form-item label="用户性别">
					<el-radio-group v-model="formData.sex">
						<el-radio :label="1">男</el-radio>
						<el-radio :label="0">女</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="出生日期" prop="birthdate">
					<el-date-picker
						type="date"
						value-format="YYYY-MM-DD"
						placeholder="请选择出生日期"
						v-model="formData.birthdate" />
				</el-form-item>
				<el-form-item label="手机号码" prop="phone">
					<el-input placeholder="请输入手机号码" v-model="formData.phone" />
				</el-form-item>
			</el-form>
			<el-divider content-position="left">建档信息（完善后部分医院首次就诊不排队建档）</el-divider>
			<el-form :model="formData" :rules="rules" label-width="120px" ref="ruleFormRef2">
				<el-form-item label="婚姻状况">
					<el-radio-group v-model="formData.isMarry">
						<el-radio :label="1">已婚</el-radio>
						<el-radio :label="0">未婚</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="自费/医保">
					<el-radio-group v-model="formData.isInsure">
						<el-radio :label="1">自费</el-radio>
						<el-radio :label="0">医保</el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="当前住址" prop="addressSelected">
					<el-cascader
						placeholder="请选择当前住址"
						:props="cascaderProps"
						v-model="formData.addressSelected" />
				</el-form-item>
				<el-form-item label="详细地址" prop="address">
					<el-input placeholder="请输入详细地址" v-model="formData.address" />
				</el-form-item>
			</el-form>
			<el-divider content-position="left">联系人信息（选填）</el-divider>
			<el-form :model="formData" :rules="rules" label-width="120px" ref="ruleFormRef3">
				<el-form-item label="用户姓名" prop="contactsName">
					<el-input placeholder="请输入用户姓名" v-model="formData.contactsName" />
				</el-form-item>
				<el-form-item label="证件类型" prop="contactsCertificatesType">
					<el-select placeholder="请选择证件类型" v-model="formData.contactsCertificatesType">
						<el-option
							v-for="item in certationType"
							:key="item.id"
							:label="item.name"
							:value="item.value" />
					</el-select>
				</el-form-item>
				<el-form-item label="证件号码" prop="contactsCertificatesNo">
					<el-input placeholder="请输入证件号码" v-model="formData.contactsCertificatesNo" />
				</el-form-item>
				<el-form-item label="手机号码" prop="contactsPhone">
					<el-input placeholder="请输入手机号码" v-model="formData.contactsPhone" />
				</el-form-item>
				<el-form-item>
					<el-button type="primary" @click="submit">提交</el-button>
					<el-button @click="reset">重写</el-button>
				</el-form-item>
			</el-form>
		</div>
	</el-card>
</template>

<script setup lang="ts">
import { User, ArrowLeft } from '@element-plus/icons-vue';
import Visitor from '@/components/visitor/index.vue';
import { getPatientInfo } from '@/api/hospital';
import { Patient } from '@/api/hospital/type';
import { ref, computed, reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { type FormInstance, type CascaderProps, type FormRules, ElMessage } from 'element-plus';
import { getCertationType, getCity, addAndupdatePatient, getPatientById, deletePatientById } from '@/api/user';
import { CertificatesType, SubmitPatientData } from '@/api/user/type';

const ruleFormRef1 = ref<FormInstance>();
const ruleFormRef2 = ref<FormInstance>();
const ruleFormRef3 = ref<FormInstance>();

const route = useRoute();
const router = useRouter();

const formData = reactive<SubmitPatientData>({
	name: '',
	certificatesType: '',
	certificatesNo: '',
	sex: 0,
	birthdate: '',
	phone: '',
	isMarry: 0,
	isInsure: 0,
	addressSelected: [],
	address: '',
	contactsName: '',
	contactsCertificatesType: '',
	contactsCertificatesNo: '',
	contactsPhone: '',
});

function certificatesNoRules<T extends SubmitPatientData, K extends keyof T>(obj: T, key: K, s = false) {
	return function (_rule: any, value: any, callback: Function) {
		if (s && !value) return callback();

		if (obj[key]) {
			if (!/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value) || !/^(\d{17})(\d|X)$/.test(value)) {
				callback('验证不通过，请检查格式');
			} else {
				callback();
			}
		} else {
			callback('请先选择证件类型');
		}
	};
}

function phoneRules(s = false) {
	return function (_rule: any, value: any, callback: Function) {
		if (!value) {
			if (s) {
				callback();
			} else {
				callback('手机号不能为空');
			}
		} else if (value.length !== 11) {
			callback('手机号需要为11位');
		} else if (!/^1[3-9]\d{9}$/.test(value)) {
			callback('手机号格式不正确');
		}

		callback();
	};
}

const rules: FormRules = {
	name: { required: true, message: '用户姓名不能为空' },
	certificatesType: { required: true, message: '请选择证件类型' },
	certificatesNo: [
		{ required: true, message: '证件号码不能为空' },
		{ validator: certificatesNoRules(formData, 'certificatesType') },
	],
	birthdate: { required: true, message: '出生日期不能为空' },
	phone: [{ required: true, message: '手机号码不能为空' }, { validator: phoneRules() }],
	addressSelected: { required: true, message: '请选择当前住址' },
	address: { required: true, message: '详细地址不能为空' },

	contactsCertificatesNo: { validator: certificatesNoRules(formData, 'contactsCertificatesType', true) },
	contactsPhone: { validator: phoneRules(true) },
};

let scene = computed(() => {
	reset();

	let r = 0;
	if (route.query.type) {
		switch (route.query.type) {
			case 'add':
				r = 1;
				getCertationTypeFn();
				break;
			case 'edit':
				r = 2;
				getCertationTypeFn();
				getPatientInfoItem();
				break;
		}
	}

	if (r === 0) {
		getPatientInfoFn();
	}

	return r;
});

let patientInfo = ref<Patient[]>([]);

let loading = ref(false);
let formLoading = ref(false);

let certationType = ref<CertificatesType[]>([]);

const cascaderProps: CascaderProps = {
	lazy: true,
	lazyLoad(node, resolve) {
		getCity((node.data?.id as string) || '86').then((res) => {
			const data = res.data.map((item) => {
				return {
					id: item.id,
					value: item.value,
					label: item.name,
					leaf: !item.hasChildren,
				};
			});

			resolve(data);
		});
	},
};

// 获取所有就诊人信息
function getPatientInfoFn(callback?: Function) {
	loading.value = true;
	getPatientInfo()
		.then((res) => {
			if (res.ok) {
				patientInfo.value = res.data;
			}
		})
		.finally(() => {
			loading.value = false;
			callback && callback();
		});
}

// 添加就诊人
function addPatient() {
	router.push({
		path: '/user/patient',
		query: {
			type: 'add',
		},
	});
}

// 编辑就诊人
function editPatient(id: number) {
	router.push({
		path: '/user/patient',
		query: {
			type: 'edit',
			id,
		},
	});
}

// 获取证件类型
function getCertationTypeFn() {
	getCertationType().then((res) => {
		if (res.ok) {
			certationType.value = res.data;
		}
	});
}

// 重写
function reset() {
	delete formData.id;

	Object.assign(formData, {
		name: '',
		certificatesType: '',
		certificatesNo: '',
		sex: 0,
		birthdate: '',
		phone: '',
		isMarry: 0,
		isInsure: 0,
		addressSelected: [],
		address: '',
		contactsName: '',
		contactsCertificatesType: '',
		contactsCertificatesNo: '',
		contactsPhone: '',
	});
}

// 编辑模式下获取单个就诊人信息
function getPatientInfoItem() {
	const id = Number(route.query.id);

	formLoading.value = true;

	getPatientById(id)
		.then((res) => {
			if (res.ok) {
				let newObj = JSON.parse(JSON.stringify(res.data));

				Object.keys(formData).forEach((key) => {
					// @ts-ignore
					formData[key] = newObj[key];
				});
			} else {
				ElMessage.error('获取就诊人信息失败');
			}
		})
		.finally(() => {
			formLoading.value = false;
		});
}

// 提交回调
async function submit() {
	if (!ruleFormRef1.value || !ruleFormRef2.value || !ruleFormRef3.value) return;

	try {
		const [s1, s2, s3] = await Promise.all([
			ruleFormRef1.value.validate(),
			ruleFormRef2.value.validate(),
			ruleFormRef3.value.validate(),
		]);

		if (s1 && s2 && s3) {
			const submitData: SubmitPatientData = JSON.parse(JSON.stringify(formData));
			let prefix = '';

			const [t1, t2, t3] = submitData.addressSelected;

			submitData.provinceCode = t1;
			submitData.cityCode = t2;
			submitData.districtCode = t3;

			// provinceCode?: string;
			// cityCode?: string;
			// districtCode?: string;

			if (scene.value === 1) {
				prefix = '添加';
			} else if (scene.value === 2) {
				prefix = '修改';

				submitData.id = Number(route.query.id);
			}

			try {
				const res = await addAndupdatePatient(submitData);

				if (res.ok) {
					ElMessage.success(prefix + '成功');
				} else {
					ElMessage.success(prefix + '失败');
				}
			} catch (error) {
				ElMessage.success(prefix + '失败');
			} finally {
				router.back();
			}
		}
	} catch (error) {
		return;
	}
}

// 删除就诊人
function deletePatientByIdFn(id: number) {
	deletePatientById(id)
		.then(
			(res) => {
				if (res.ok) {
					ElMessage.success('删除成功');
				} else {
					ElMessage.error('删除失败');
				}
			},
			() => {
				ElMessage.error('删除失败');
			}
		)
		.finally(() => {
			getPatientInfoFn();
		});
}
</script>

<style scoped lang="scss">
.box-card {
	margin-bottom: 40px;
	:deep(.el-card__body) {
		padding-bottom: 0;
	}
	.card-header {
		display: flex;
		justify-content: space-between;
	}
	.visitor_box {
		display: flex;
		flex-wrap: wrap;
		min-height: 200px;
		.visitor {
			width: calc(33.33333% - 14px);
			margin-right: 21px;
			margin-bottom: 20px;
			&:nth-child(3n + 3) {
				margin-right: 0;
			}
		}
	}
	.form {
		display: flex;
		flex-direction: column;
		align-items: center;
		padding-bottom: 20px;
		:deep(.el-divider:not(:first-child)) {
			margin-top: 40px;
		}
		:deep(.el-form) {
			width: calc(100% - 36px);
		}
	}
}
</style>
